package com.lgl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lgl.dto.AddRoleDto;
import com.lgl.dto.RoleDto;
import com.lgl.dto.UpdateRoleDto;
import com.lgl.entity.ResponseResult;
import com.lgl.entity.Role;
import com.lgl.entity.RoleMenu;
import com.lgl.entity.UserRole;
import com.lgl.mapper.RoleMapper;
import com.lgl.service.RoleMenuService;
import com.lgl.service.RoleService;
import com.lgl.service.UserRoleService;
import com.lgl.utils.BeanCopyUtils;
import com.lgl.utils.SecurityUtils;
import com.lgl.vo.GetRoleVo;
import com.lgl.vo.ListAllRoleVo;
import com.lgl.vo.PageVo;
import com.lgl.vo.RoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private RoleMenuService roleMenuService;

    @Override
    public List<String> selectRoleKeyByUserId(Long id) {
        //判断是否是管理员 如果是返回集合中只需要有admin
        if (id == 1L) {
            List<String> roleKeys = new ArrayList<>();
            roleKeys.add("admin");
            return roleKeys;
        }
        //否则查询用户所具有的角色信息
        return getBaseMapper().selectRoleKeyByUserId(id);
    }

    @Override
    public List<Role> selectRoleByUserId(Long id) {
        //判断是否是管理员 如果是返回集合中只需要有admin
        if (id == 1L) {
            List<Role> roles = new ArrayList<>();
            Role role = getById(1L);
            roles.add(role);
            return roles;
        }
        //否则查询用户所具有的角色信息
        return getBaseMapper().selectRoleByUserId(id);
    }

    @Override
    public ResponseResult getRoleList(Integer pageSize, Integer pageNum, String roleName, String status) {
//     需要有角色列表分页查询的功能。
//
//     要求能够针对角色名称进行模糊查询。
//
//     要求能够针对状态进行查询。
//
//     要求按照role_sort进行升序排列。
        Page<Role> rolePage = new Page<>();
        rolePage.setSize(pageSize);
        rolePage.setCurrent(pageNum);
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(roleName), Role::getRoleName, roleName);
        queryWrapper.eq(StringUtils.hasText(status), Role::getStatus, status);
        queryWrapper.orderByAsc(Role::getRoleSort);
        Page<Role> page = page(rolePage, queryWrapper);
        List<Role> records = page.getRecords();
        List<RoleVo> roleVos = BeanCopyUtils.copyBeanList(records, RoleVo.class);
        PageVo pageVo = new PageVo(roleVos, page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult changeStatus(RoleDto roleDto) {
        getBaseMapper().updateStatusByRoleId(roleDto);
        return ResponseResult.okResult();
    }

    @Override
    @Transactional
    public ResponseResult addRole(AddRoleDto addRoleDto) {
        Role role = BeanCopyUtils.beanCopy(addRoleDto, Role.class);
        save(role);
        ArrayList<RoleMenu> roleMenus = new ArrayList<>();
        for (Long menuId : addRoleDto.getMenuIds()) {
            RoleMenu roleMenu = new RoleMenu(role.getId(), menuId);
            roleMenus.add(roleMenu);
        }
        roleMenuService.saveBatch(roleMenus);
        if (SecurityUtils.isAdmin()){
            return ResponseResult.okResult();
        }
        UserRole userRole = new UserRole(SecurityUtils.getUserId(), role.getId());
        userRoleService.save(userRole);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getRole(Long id) {
        Role role = getById(id);
        GetRoleVo getRoleVo = BeanCopyUtils.beanCopy(role, GetRoleVo.class);
        return ResponseResult.okResult(getRoleVo);
    }

    @Override
    @Transactional
    public ResponseResult updateRole(UpdateRoleDto updateRoleDto) {
        Role role = BeanCopyUtils.beanCopy(updateRoleDto, Role.class);
        updateById(role);
        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleMenu::getRoleId,updateRoleDto.getId());
        roleMenuService.remove(queryWrapper);
        List<RoleMenu> menuIds = new ArrayList<>();
        for (Long menuId : updateRoleDto.getMenuIds()) {
            RoleMenu roleMenu = new RoleMenu(updateRoleDto.getId(), menuId);
            menuIds.add(roleMenu);
        }
        roleMenuService.saveBatch(menuIds);
        return ResponseResult.okResult();
    }

    @Override
    @Transactional
    public ResponseResult deleteRole(Long id) {
        removeById(id);
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getRoleId,id);
        LambdaQueryWrapper<RoleMenu> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(RoleMenu::getRoleId,id);
        userRoleService.remove(queryWrapper);
        roleMenuService.remove(queryWrapper2);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult listAllRole() {
        List<Role> list = list();
        List<ListAllRoleVo> listAllRoleVos = BeanCopyUtils.copyBeanList(list, ListAllRoleVo.class);
        return ResponseResult.okResult(listAllRoleVos);
    }
}